# Bazel build
# C/C++ documentation: https://docs.bazel.build/versions/master/be/c-cpp.html

load("@rules_proto_grpc//python:defs.bzl", "python_proto_compile")
load("//bazel:ray.bzl", "COPTS", "copy_to_workspace")

proto_library(
    name = "streaming_proto",
    srcs = ["src/protobuf/streaming.proto"],
    strip_import_prefix = "src",
    visibility = ["//visibility:public"],
    deps = [
        "@com_google_protobuf//:any_proto",
    ],
)

proto_library(
    name = "streaming_queue_proto",
    srcs = ["src/protobuf/streaming_queue.proto"],
    strip_import_prefix = "src",
)

proto_library(
    name = "remote_call_proto",
    srcs = ["src/protobuf/remote_call.proto"],
    strip_import_prefix = "src",
    visibility = ["//visibility:public"],
    deps = [
        "streaming_proto",
        "@com_google_protobuf//:any_proto",
    ],
)

cc_proto_library(
    name = "streaming_cc_proto",
    deps = [":streaming_proto"],
)

cc_proto_library(
    name = "streaming_queue_cc_proto",
    deps = ["streaming_queue_proto"],
)

# Use `linkshared` to ensure ray related symbols are not packed into streaming libs
# to avoid duplicate symbols. In runtime we expose ray related symbols, which can
# be linked into streaming libs by dynamic linker. See bazel rule `//:_raylet`
cc_binary(
    name = "ray_util.so",
    copts = COPTS,
    linkshared = 1,
    visibility = ["//visibility:public"],
    deps = ["//:ray_util"],
)

cc_binary(
    name = "ray_common.so",
    copts = COPTS,
    linkshared = 1,
    visibility = ["//visibility:public"],
    deps = ["//:ray_common"],
)

cc_binary(
    name = "core_worker_lib.so",
    copts = COPTS,
    linkshared = 1,
    deps = ["//:core_worker_lib"],
)

cc_binary(
    name = "exported_streaming_internal.so",
    copts = COPTS,
    linkshared = 1,
    deps = ["//:exported_streaming_internal"],
)

cc_library(
    name = "streaming_util",
    srcs = glob([
        "src/util/*.cc",
    ]),
    hdrs = glob([
        "src/util/*.h",
    ]),
    copts = COPTS,
    includes = ["src"],
    visibility = ["//visibility:public"],
    deps = [
        "ray_common.so",
        "ray_util.so",
        "@boost//:any",
        "@com_google_googletest//:gtest",
    ],
)

cc_library(
    name = "streaming_config",
    srcs = glob([
        "src/config/*.cc",
    ]),
    hdrs = glob([
        "src/config/*.h",
    ]),
    copts = COPTS,
    strip_include_prefix = "src",
    deps = [
        "ray_common.so",
        ":streaming_cc_proto",
        ":streaming_util",
    ],
)

cc_library(
    name = "streaming_message",
    srcs = glob([
        "src/message/*.cc",
    ]),
    hdrs = glob([
        "src/message/*.h",
    ]),
    copts = COPTS,
    strip_include_prefix = "src",
    deps = [
        "ray_common.so",
        ":streaming_config",
        ":streaming_util",
    ],
)

cc_library(
    name = "streaming_queue",
    srcs = glob([
        "src/queue/*.cc",
    ]),
    hdrs = glob([
        "src/queue/*.h",
    ]),
    copts = COPTS,
    strip_include_prefix = "src",
    deps = [
        "ray_common.so",
        "ray_util.so",
        ":streaming_config",
        ":streaming_message",
        ":streaming_queue_cc_proto",
        ":streaming_util",
        "@boost//:asio",
        "@boost//:thread",
    ] + select({
        "@bazel_tools//src/conditions:windows": [
            # TODO(mehrdadn): This is to resolve symbols on Windows for now. Should remove this later. (See d7f8d18.)
            "//:core_worker_lib",
            "//:exported_streaming_internal",
        ],
        "//conditions:default": [
            "core_worker_lib.so",
            "exported_streaming_internal.so",
        ],
    }),
)

cc_library(
    name = "streaming_channel",
    srcs = glob(["src/channel/*.cc"]),
    hdrs = glob(["src/channel/*.h"]),
    copts = COPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":streaming_common",
        ":streaming_message",
        ":streaming_queue",
        ":streaming_ring_buffer",
        ":streaming_util",
    ],
)

cc_library(
    name = "streaming_reliability",
    srcs = glob(["src/reliability/*.cc"]),
    hdrs = glob(["src/reliability/*.h"]),
    copts = COPTS,
    includes = ["src/"],
    visibility = ["//visibility:public"],
    deps = [
        ":streaming_channel",
        ":streaming_message",
        ":streaming_util",
    ],
)

cc_library(
    name = "streaming_ring_buffer",
    srcs = glob(["src/ring_buffer/*.cc"]),
    hdrs = glob(["src/ring_buffer/*.h"]),
    copts = COPTS,
    includes = ["src/"],
    visibility = ["//visibility:public"],
    deps = [
        "core_worker_lib.so",
        ":ray_common.so",
        ":ray_util.so",
        ":streaming_message",
        "@boost//:circular_buffer",
        "@boost//:thread",
    ],
)

cc_library(
    name = "streaming_common",
    srcs = glob(["src/common/*.cc"]),
    hdrs = glob(["src/common/*.h"]),
    copts = COPTS,
    includes = ["src/"],
    visibility = ["//visibility:public"],
    deps = [],
)

cc_library(
    name = "streaming_lib",
    srcs = glob([
        "src/*.cc",
    ]),
    hdrs = glob([
        "src/*.h",
        "src/queue/*.h",
        "src/test/*.h",
    ]),
    copts = COPTS,
    strip_include_prefix = "src",
    visibility = ["//visibility:public"],
    deps = [
        "ray_common.so",
        "ray_util.so",
        ":streaming_channel",
        ":streaming_common",
        ":streaming_config",
        ":streaming_message",
        ":streaming_queue",
        ":streaming_reliability",
        ":streaming_util",
    ],
)

test_common_deps = [
    "//:exported_streaming_internal",
    ":streaming_lib",
    "//:ray_common",
    "//:ray_util",
    "//:core_worker_lib",
]

# streaming queue mock actor binary
cc_binary(
    name = "streaming_test_worker",
    srcs = glob(["src/test/*.h"]) + [
        "src/test/mock_actor.cc",
    ],
    copts = COPTS,
    deps = test_common_deps,
)

# use src/test/run_streaming_queue_test.sh to run this test
cc_binary(
    name = "streaming_queue_tests",
    srcs = glob(["src/test/*.h"]) + [
        "src/test/streaming_queue_tests.cc",
    ],
    copts = COPTS,
    deps = test_common_deps,
)

cc_test(
    name = "streaming_message_ring_buffer_tests",
    srcs = [
        "src/test/ring_buffer_tests.cc",
    ],
    copts = COPTS,
    deps = test_common_deps,
)

cc_test(
    name = "barrier_helper_tests",
    srcs = [
        "src/test/barrier_helper_tests.cc",
    ],
    copts = COPTS,
    deps = test_common_deps,
)

cc_test(
    name = "streaming_message_serialization_tests",
    srcs = [
        "src/test/message_serialization_tests.cc",
    ],
    copts = COPTS,
    deps = test_common_deps,
)

cc_test(
    name = "streaming_mock_transfer",
    srcs = [
        "src/test/mock_transfer_tests.cc",
    ],
    copts = COPTS,
    deps = test_common_deps,
)

cc_test(
    name = "streaming_util_tests",
    srcs = [
        "src/test/streaming_util_tests.cc",
    ],
    copts = COPTS,
    deps = test_common_deps,
)

cc_test(
    name = "event_service_tests",
    srcs = [
        "src/test/event_service_tests.cc",
    ],
    copts = COPTS,
    deps = test_common_deps,
)

cc_test(
    name = "queue_protobuf_tests",
    srcs = [
        "src/test/queue_protobuf_tests.cc",
    ],
    deps = test_common_deps,
)

cc_test(
    name = "data_writer_tests",
    srcs = [
        "src/test/data_writer_tests.cc",
    ],
    copts = COPTS,
    deps = test_common_deps,
)

python_proto_compile(
    name = "streaming_py_proto",
    deps = [":streaming_proto"],
)

python_proto_compile(
    name = "remote_call_py_proto",
    deps = [":remote_call_proto"],
)

filegroup(
    name = "all_py_proto",
    srcs = [
        ":remote_call_py_proto",
        ":streaming_py_proto",
    ],
)

copy_to_workspace(
    name = "cp_all_py_proto",
    srcs = [":all_py_proto"],
    dstdir = "streaming/python/generated",
)

genrule(
    name = "copy_streaming_py_proto",
    srcs = [
        ":cp_all_py_proto",
    ],
    outs = [
        "copy_streaming_py_proto.out",
    ],
    cmd = """
        GENERATED_DIR="streaming/python/generated"
        mkdir -p "$$GENERATED_DIR"
        touch "$$GENERATED_DIR/__init__.py"
        # Use this `sed` command to change the import path in the generated file.
        sed -i -E 's/from streaming.src.protobuf/from ./' "$$GENERATED_DIR/remote_call_pb2.py"
        sed -i -E 's/from protobuf/from ./' "$$GENERATED_DIR/remote_call_pb2.py"
        date > $@
    """,
    local = 1,
    visibility = ["//visibility:public"],
)

cc_binary(
    name = "libstreaming_java.so",
    srcs = glob([
        "src/lib/java/*.cc",
        "src/lib/java/*.h",
    ]),
    copts = COPTS,
    linkshared = 1,
    visibility = ["//visibility:public"],
    deps = [
        ":streaming_lib",
        "@bazel_tools//tools/jdk:jni",
    ],
)
